﻿using System;
using Moq;
using NUnit.Framework;
using Rainbow.Exceptions;
using Rainbow.ObjectFlow.Engine;
using Rainbow.ObjectFlow.Framework;
using Rainbow.ObjectFlow.Interfaces;
using Rainbow.ObjectFlow.Language;
using Shouldly;
using Objectflow.core.tests.TestOperations;

namespace Objectflow.core.tests
{
    public class WorkflowTests
    {
        [Test]
        public void Configure_should_create_exception_handler()
        {
            Workflow<string>.Definition().Configure().ShouldBeTypeOf<IHandle>();
        }

        [Test]
        public void Instance_Configure_should_create_exception_handler()
        {
            var workflow = new Workflow<string>() as IDefine<string>;
            workflow.Configure().ShouldBeTypeOf<IHandle>();
        }

        [Test]
        public void Workflow_should_configure_exceptions()
        {
            var t = new Workflow<string>();
            t.Configure().ShouldBeTypeOf<IHandle>();

        }

        [Test]
        public void Start_should_use_exception_handler()
        {
            var handler = new Mock<ExceptionHandler>();

            var workflow = new Workflow<string>();
            workflow.ExceptionHandler = handler.Object;
            workflow.Do((d) => { throw new ExecutionEngineException(); });
            workflow.Start();

            handler.Setup(x => x.When(() => workflow.Start()));
        }

        [Test]
        public void Should_initialiase_exception_handler_when_not_specified()
        {
            var workflow = new Workflow<string>();
            workflow.Do((d) => "red").Start();
        }

        [Test]
        public void Seed_start_should_use_exception_handler()
        {
            var handler = new Mock<ExceptionHandler>();

            var workflow = new Workflow<string>();
            workflow.ExceptionHandler = handler.Object;
            workflow.Do((d) => { throw new ExecutionEngineException(); });
            workflow.Start();

            handler.Setup(x => x.When(() => workflow.Start("red")));
        }

        public class WhenStartingWorkflow
        {
            [Test]
            public void Start_should_create_default_state_when_non_supplied()
            {
                var engine = new Mock<Dispatcher<Colour>>();
                var taskList = new TaskList<Colour>();
                var workflow = new Workflow<Colour>(engine.Object, taskList);

                var result = workflow.Start();
                engine.Verify(x => x.Execute(taskList.Tasks, It.IsAny<Colour>()));
            }
        }
    }
}